//! \file memory.hpp
//! \brief Purewell Library Memory Header
//! \author Yubin Lim (purewell@gmail.com)
//! \since 2008-11-05

#ifndef __PWHDR_MEMORY_HPP__
#define __PWHDR_MEMORY_HPP__

#include "types.hpp"

namespace purewell
{

class PWFile;

//! \brief Memory class. It's auto-pointer.
class PWAPI PWMemory
{
public:

	//! \brief Memory type.
	typedef enum _MEM_TYPE
	{
		MEM_NONE,	//!< Invalid type.
		MEM_NORMAL,	//!< Normal type.
		MEM_FILE,	//!< File mapping type.
	} MEM_TYPE;

public:
	//! \brief Create memory.
	//! \param[in] size Memory size.
	//! \return On success, memory pointer or NULL.
	static PWMemory* create(size_t size);

	//! \brief Create file-mapped memory.
	//! \param[in] size Memory size.
	//! \param[in] file File to be mapped.
	//! \param[in] offset File offset.
	//! \param[in] omode Memory open mode.
	//! \param[in] flag Memory flags.
	//! \param[in] startptr Start pointer.
	//! \return On success, memory pointer or NULL.
	static PWMemory* create(size_t size, PWFile& file,
		off_t offset = 0, int omode = PWMEM_OMODE_DEFAULT,
		int flag = PWMEM_FILE_DEFAULT, void* startptr = NULL);

	//! \brief Create file-mapped memory.
	//! \param[in] size Memory size.
	//! \param[in] fd File descriptor.
	//! \param[in] offset File offset.
	//! \param[in] omode Memory open mode.
	//! \param[in] flag Memory flags.
	//! \param[in] startptr Start pointer.
	//! \return On success, memory pointer or NULL.
	static PWMemory* create(size_t size, int fd,
		off_t offset = 0, int omode = PWMEM_OMODE_DEFAULT,
		int flag = PWMEM_FILE_DEFAULT, void* startptr = NULL);

	//! \brief Release memory.
	//! \param[in] obj Memory object to release.
	static void release(PWMemory* obj);

public:
	//! \brief Get memory type.
	//! \return Memory type.
	MEM_TYPE getType(void) const;

	//! \brief Get memory size.
	//! \return Memory size.
	size_t getSize(void) const;

	//! \brief Get memory block.
	//! \return Memory block pointer.
	const void* getMemory(void) const;

	//! \brief Get memory block.
	//! \return Memory block pointer.
	void* getMemory(void);

	//! \brief Get memory block.
	//! \return Memory block pointer.
	void* operator () (void);

	//! \brief Get memory block.
	//! \return Memory block pointer.
	const void* operator () (void) const;

private:
	explicit PWMemory(size_t size);
	explicit PWMemory(void* ptr, int fd, off_t offset,
		size_t size, int omode, int flag);
	virtual ~PWMemory();
	inline PWMemory& operator = (const PWMemory&) { return *this; }

private:
	void*	m_pData;
};

};//namespace purewell


#endif//!__PWHDR_MEMORY_HPP__

